class ZVue {
    constructor(options) {
        this.$options = options
        this.$data = options.data
        // 设置$data数据在this上的依赖
        this.observer(this.$data)   
        this.$compile = new Compile(options.el,this)
        if (options.created) {
            options.created.call(this)
        }
    }
    observer(data) {
        Object.keys(data).forEach(key => {        
            this.proxyData(key)
            this.defineReactive(data, key, data[key])
        })
    }
    defineReactive(obj, key, val) {
        // 新建依赖
        const dep = new Dep()
        Object.defineProperty(obj, key, {
            get() {
                Dep.target && dep.addDep(Dep.target)
                return val
            },
            set(newVal) {       
                val = newVal
                dep.nptify()
            }
        })
    }
    proxyData(key) {
        Object.defineProperty(this, key, {
            get() {
                return this.$data[key]
            },
            set(val) {
                this.$data[key] = val
            }
        })
    }
}

// 依赖收集
class Dep {
    constructor() {
        this.deps = []
    }
    addDep(dep) {
        // 添加依赖
        this.deps.push(dep)
    }
    nptify() {
        // 通知更新
        this.deps.forEach(dep => {
            // 遍历
            // 执行更新函数
            dep.update()
        })
    }
}

Dep.target = null

// 监听器
class watch {
    constructor(vm,exp,cb) {
        this.vm = vm
        this.cb = cb
        this.exp = exp
        this.value = this.get()
    }
    update() {
        this.value = this.get()
        this.cb.call(this.vm,this.value)
    }
    get(){
        // 收集依赖
        Dep.target = this
        // 读数据，自动收集
        let value = this.vm[this.exp]
        Dep.target = null
        return value
    }
}